package com.southminority.ethnic.controller.document;

import com.southminority.ethnic.common.result.R;
import com.southminority.ethnic.service.document.DocumentService;
import com.southminority.ethnic.controller.document.vo.DocumentVO;
import com.southminority.ethnic.vo.ShareInfoVO;
import com.southminority.ethnic.controller.document.vo.FileTypeInfoVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import java.time.LocalDateTime;

/**
 * 古籍文献前端API控制器
 * 
 * @author SouthMinority
 */
@Slf4j
@Tag(name = "古籍文献展示", description = "用于前端展示、查询和下载古籍文献的公共接口")
@RestController
@RequestMapping("/api/document")
@CrossOrigin
public class DocumentController {

    private final DocumentService documentService;

    public DocumentController(DocumentService documentService) {
        this.documentService = documentService;
    }

    @GetMapping("/featured")
    @Operation(summary = "获取首页特色文献", description = "获取设置为首页展示且排序最靠前的一篇古籍文献")
    @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = DocumentVO.class)))
    public R<DocumentVO> getFeaturedDocument() {
        try {
            DocumentVO documentVO = documentService.getFeaturedDocument();
            return R.ok(documentVO);
        } catch (Exception e) {
            log.error("获取首页古籍文献失败", e);
            return R.fail("获取古籍文献失败: " + e.getMessage());
        }
    }

    @GetMapping("/homepage-list")
    @Operation(summary = "获取首页文献列表", description = "获取所有设置为在首页展示的古籍文献列表，按指定顺序排序")
    @ApiResponse(responseCode = "200", description = "获取成功")
    public R<List<DocumentVO>> getHomepageDocumentList() {
        try {
            List<DocumentVO> documentList = documentService.getHomepageDocumentList();
            return R.ok(documentList);
        } catch (Exception e) {
            log.error("获取首页古籍文献列表失败", e);
            return R.fail("获取首页古籍文献列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/detail/{id}")
    @Operation(summary = "获取古籍文献详情", description = "根据ID获取单个古籍文献的详细信息")
    @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = DocumentVO.class)))
    @ApiResponse(responseCode = "404", description = "文献不存在")
    public R<DocumentVO> getDocumentDetail(@Parameter(description = "古籍文献ID", required = true, example = "1") @PathVariable Long id) {
        try {
            DocumentVO documentVO = documentService.getDocumentDetail(id);
            return R.ok(documentVO);
        } catch (Exception e) {
            log.error("获取古籍文献详情失败", e);
            return R.fail("获取古籍文献详情失败: " + e.getMessage());
        }
    }

    @GetMapping("/list")
    @Operation(summary = "获取所有文献列表", description = "获取所有已发布的古籍文献列表（不分页）")
    @ApiResponse(responseCode = "200", description = "获取成功")
    public R<List<DocumentVO>> getDocumentList() {
        try {
            List<DocumentVO> documentList = documentService.getDocumentList();
            return R.ok(documentList);
        } catch (Exception e) {
            log.error("获取古籍文献列表失败", e);
            return R.fail("获取古籍文献列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/category/{categoryId}")
    @Operation(summary = "按分类获取文献列表", description = "根据分类ID获取该分类下的所有古籍文献列表")
    @ApiResponse(responseCode = "200", description = "获取成功")
    public R<List<DocumentVO>> getDocumentListByCategory(@Parameter(description = "分类ID", required = true, example = "1") @PathVariable Long categoryId) {
        try {
            List<DocumentVO> documentList = documentService.getDocumentListByCategory(categoryId);
            return R.ok(documentList);
        } catch (Exception e) {
            log.error("按分类获取古籍文献列表失败", e);
            return R.fail("获取古籍文献列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/type/{documentType}")
    @Operation(summary = "按文献类型获取列表", description = "根据文献类型（如'古籍', '手稿'）获取古籍文献列表")
    @ApiResponse(responseCode = "200", description = "获取成功")
    public R<List<DocumentVO>> getDocumentListByType(@Parameter(description = "文献类型", required = true, example = "古籍") @PathVariable String documentType) {
        try {
            List<DocumentVO> documentList = documentService.getDocumentListByType(documentType);
            return R.ok(documentList);
        } catch (Exception e) {
            log.error("按文献类型获取古籍文献列表失败", e);
            return R.fail("获取古籍文献列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/dynasty/{dynasty}")
    @Operation(summary = "按朝代获取文献列表", description = "根据朝代获取古籍文献列表")
    @ApiResponse(responseCode = "200", description = "获取成功")
    public R<List<DocumentVO>> getDocumentListByDynasty(@Parameter(description = "朝代", required = true, example = "清朝") @PathVariable String dynasty) {
        try {
            List<DocumentVO> documentList = documentService.getDocumentListByDynasty(dynasty);
            return R.ok(documentList);
        } catch (Exception e) {
            log.error("按朝代获取古籍文献列表失败", e);
            return R.fail("获取古籍文献列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/search")
    @Operation(summary = "搜索古籍文献", description = "根据关键词搜索古籍文献，匹配标题、作者、描述等字段")
    @ApiResponse(responseCode = "200", description = "搜索成功")
    public R<List<DocumentVO>> searchDocuments(@Parameter(description = "搜索关键词", required = true, example = "水书") @RequestParam String keyword) {
        try {
            List<DocumentVO> documentList = documentService.searchDocuments(keyword);
            return R.ok(documentList);
        } catch (Exception e) {
            log.error("搜索古籍文献失败", e);
            return R.fail("搜索古籍文献失败: " + e.getMessage());
        }
    }

    @PostMapping("/view/{id}")
    @Operation(summary = "增加浏览次数", description = "为指定ID的文献增加一次浏览次数（view_count）")
    @ApiResponse(responseCode = "200", description = "操作成功")
    public R<Boolean> increaseViewCount(@Parameter(description = "古籍文献ID", required = true, example = "1") @PathVariable Long id) {
        try {
            documentService.increaseViewCount(id);
            return R.ok(true);
        } catch (Exception e) {
            log.error("增加浏览次数失败", e);
            return R.fail("增加浏览次数失败: " + e.getMessage());
        }
    }

    @PostMapping("/download-count/{id}")
    @Operation(summary = "增加下载次数", description = "为指定ID的文献增加一次下载次数（download_count），前端在调用下载接口前应先调用此接口")
    @ApiResponse(responseCode = "200", description = "操作成功")
    public R<Boolean> increaseDownloadCount(@Parameter(description = "古籍文献ID", required = true, example = "1") @PathVariable Long id) {
        try {
            documentService.increaseDownloadCount(id);
            return R.ok(true);
        } catch (Exception e) {
            log.error("增加下载次数失败", e);
            return R.fail("增加下载次数失败: " + e.getMessage());
        }
    }

    @GetMapping("/download/{id}")
    @Operation(summary = "下载文献主要文件", description = "根据文献ID下载其主要文件（如PDF），若无主要文件则默认尝试下载PDF。此接口将触发文件下载。")
    @ApiResponse(responseCode = "200", description = "下载成功", content = @Content(mediaType = "application/octet-stream"))
    @ApiResponse(responseCode = "302", description = "重定向到文件URL")
    @ApiResponse(responseCode = "404", description = "文献或文件不存在")
    public ResponseEntity<?> downloadDocumentFile(
            @Parameter(description = "古籍文献ID", required = true, example = "1") @PathVariable Long id,
            @Parameter(description = "文件类型（可选，用于兼容旧版，建议使用/file-types接口获取可用类型后下载）") @RequestParam(required = false) String fileType) {
        try {
            // 获取文档详情
            DocumentVO documentVO = documentService.getDocumentDetail(id);
            if (documentVO == null) {
                return ResponseEntity.notFound().build();
            }

            String fileUrl = null;
            String fileName = documentVO.getTitle();
            
            // 如果没有指定文件类型，则下载主要文件
            if (fileType == null || fileType.isEmpty()) {
                // 优先使用主要文件URL，如果没有则使用PDF URL
                fileUrl = documentVO.getPrimaryFileUrl();
                if (fileUrl != null && !fileUrl.isEmpty()) {
                    // 使用主要文件的原始名称，如果没有则生成默认名称
                    if (documentVO.getPrimaryFileName() != null && !documentVO.getPrimaryFileName().isEmpty()) {
                        fileName = documentVO.getPrimaryFileName();
                    } else {
                        String fileExt = documentVO.getPrimaryFileType() != null ? "." + documentVO.getPrimaryFileType() : ".pdf";
                        fileName += fileExt;
                    }
                } else {
                    // 如果没有主要文件，回退到PDF
                    fileUrl = documentVO.getPdfUrl();
                    fileName += ".pdf";
                }
            } else {
                // 保持原有的分类下载逻辑（向后兼容）
                switch (fileType.toLowerCase()) {
                    case "pdf":
                        fileUrl = documentVO.getPdfUrl();
                        fileName += ".pdf";
                        break;
                    case "image":
                        // 如果有多个图片，下载第一个
                        if (documentVO.getImageUrls() != null && !documentVO.getImageUrls().isEmpty()) {
                            fileUrl = documentVO.getImageUrls().get(0);
                            fileName += ".jpg";
                        }
                        break;
                    case "audio":
                        fileUrl = documentVO.getAudioUrl();
                        fileName += ".mp3";
                        break;
                    case "video":
                        fileUrl = documentVO.getVideoUrl();
                        fileName += ".mp4";
                        break;
                    default:
                        return ResponseEntity.badRequest()
                            .body(R.fail("不支持的文件类型: " + fileType));
                }
            }

                         if (fileUrl == null || fileUrl.isEmpty()) {
                 return ResponseEntity.status(HttpStatus.NOT_FOUND)
                     .body(R.fail("该文档没有对应类型的文件"));
             }

            // 增加下载次数
            documentService.increaseDownloadCount(id);

            // 如果是外部URL（OSS等），直接重定向
            if (fileUrl.startsWith("http://") || fileUrl.startsWith("https://")) {
                HttpHeaders headers = new HttpHeaders();
                headers.add("Location", fileUrl);
                headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
                return new ResponseEntity<>(headers, HttpStatus.FOUND);
            }

                         // 如果是本地文件，读取文件内容返回
             Resource resource = new UrlResource(fileUrl);
             if (!resource.exists()) {
                 return ResponseEntity.status(HttpStatus.NOT_FOUND)
                     .body(R.fail("文件不存在"));
             }

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
            headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);

            return ResponseEntity.ok()
                .headers(headers)
                .body(resource);

        } catch (Exception e) {
            log.error("下载文档文件失败: ID={}, FileType={}", id, fileType, e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(R.fail("下载失败: " + e.getMessage()));
        }
    }

    @PostMapping("/share/{id}")
    @Operation(summary = "生成分享信息", description = "为指定文献生成分享链接、二维码等信息")
    @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = ShareInfoVO.class)))
    public R<ShareInfoVO> shareDocument(@Parameter(description = "古籍文献ID", required = true, example = "1") @PathVariable Long id) {
        try {
            ShareInfoVO shareInfo = documentService.generateShareInfo(id);
            log.info("生成分享链接: 文档ID={}, 标题={}", id, shareInfo.getTitle());
            return R.ok(shareInfo);
        } catch (Exception e) {
            log.error("获取分享链接失败: ID={}", id, e);
            return R.fail("获取分享链接失败: " + e.getMessage());
        }
    }

    @GetMapping("/qrcode/{id}")
    @Operation(summary = "获取分享二维码URL", description = "为指定文献生成分享二维码，并返回二维码图片的URL")
    @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(type = "string")))
    public R<String> generateQRCode(@Parameter(description = "古籍文献ID", required = true, example = "1") @PathVariable Long id) {
        try {
            ShareInfoVO shareInfo = documentService.generateShareInfo(id);
            return R.ok(shareInfo.getQrCodeUrl());
        } catch (Exception e) {
            log.error("生成二维码失败: ID={}", id, e);
            return R.fail("生成二维码失败: " + e.getMessage());
        }
    }

    @GetMapping("/file-types/{id}")
    @Operation(summary = "获取文献可用文件类型", description = "查询指定文献包含的所有可下载文件类型（如PDF, 图片, 音频等）")
    @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = FileTypeInfoVO.class)))
    public R<FileTypeInfoVO> getDocumentFileTypes(@Parameter(description = "古籍文献ID", required = true, example = "1") @PathVariable Long id) {
        try {
            FileTypeInfoVO fileTypes = documentService.getDocumentFileTypes(id);
            return R.ok(fileTypes);
        } catch (Exception e) {
            log.error("获取文档文件类型失败: ID={}", id, e);
            return R.fail("获取文档文件类型失败: " + e.getMessage());
        }
    }

    @GetMapping("/test")
    @Operation(summary = "测试接口连通性")
    @ApiResponse(responseCode = "200", description = "服务正常")
    public R<String> test() {
        return R.ok("古籍文献服务正常");
    }
} 
